from abc import abstractclassmethod
from abc import abstractmethod
from abc import abstractproperty
from abc import abstractstaticmethod
from random import randint

__bump_value = 0

def get_bump() -> int:
    "全局递增整数加一并返回"
    global __bump_value
    __bump_value += 1
    return __bump_value

def init_bump():
    "初始化全局递增整数"
    global __bump_value
    __bump_value = 0

init_bump()

class WebsiteSpiderMetaclass(type):
    def __new__(cls, name: str, base: tuple, attr: dict):
        cls = super().__new__(cls, name, base, attr)
        return cls

class WebsiteSpiderABC:
    """一个爬虫，其定义了::

        .config
        .fetch
        .parse
        .action
        .run

    等方法。调用时，应当特别只需要调用

    >>> ws = WebsiteSpider()
    >>> ws.config(...)
    >>> ws.run(...)
    """
    def __init__(self, name: str = None):
        """初始化爬虫实例

        :param str name: 用来标识此爬虫实例的字符串
            如果不传入，则将会自动生成一个
        """
        if name is not None:
            self.name = name
        else:
            self.name = f"{self.__class__.__name__}-{get_bump()}"

    @abstractmethod
    def config(self, *args, **kwargs):
        """配置爬虫本身，设置 cookie、UA 等等
        """
        raise NotImplemented

    @abstractmethod
    def fetch(self, uri: str):
        """定义获取网络资源的方法

        :param str uri: 网络资源标识符
        """
        raise NotImplemented

    @abstractmethod
    def parse(self, data):
        """定义解析网络资源，得到需要的数据的方法
        """
        raise NotImplemented

    @abstractmethod
    def action(self, *args, **kwargs):
        """其他处理流程
        """
        raise NotImplemented

    @abstractmethod
    def run(self, *args, **kwargs):
        """运行此爬虫
        """
        raise NotImplemented
